import { ComponentData, MasterPage } from "maishu-jueying";
import { ComponentContainer } from "components/component-container";
import { guid } from "common";
import { createService } from "components/common/base-component";
import { LocalService } from "./local-service";
import { Menu } from "components/menu/component";
import { Categories } from "components/categories/component";
import { Carousel } from "components/carousel/component";
import { ProductInfo } from "components/product-info/component";
import { ProductInfoFooter } from "components/product-info/product-info-footer";
import { PageDataRecord } from "entities";
import { MemberPage } from "components/member/component";

import { ShoppingCart } from "components/shopping-cart/component";
import { ShoppingCartFooter } from "components/shopping-cart/shopping-cart-footer";
import { ShoppingCartHeader } from "components/shopping-cart/shopping-cart-header";
import { StoreCoupons } from "components/store-coupons/component";

type PagePartTag = "header" | "section" | "footer";
let BODY_TAG: PagePartTag = "section";
let FOOTER_TAG: PagePartTag = "footer";
let HEADER_TAG: PagePartTag = "header";

function defaultHeaderData(): ComponentData {
    return {
        type: HEADER_TAG,
        children: [{
            type: ComponentContainer.name,
            props: {
                attr: { movable: false, container: false, showHandler: false, resize: false },
                id: guid(),
                text: "请拖拉控件到这里",
            }
        }]
    }
}

function defaultFooterData(): ComponentData {
    return {
        type: FOOTER_TAG,
        children: [{
            type: ComponentContainer.name,
            props: {
                attr: { movable: false, container: false, showHandler: false, resize: false, },
                id: guid(),
                text: "请拖拉控件到这里",
            }
        }]
    }
}

function defaultBodyData(): ComponentData {
    return {
        type: BODY_TAG,
        children: [{
            type: ComponentContainer.name,
            props: {
                attr: { movable: false, container: false, showHandler: false, resize: false },
                id: guid(),
                text: "请拖拉控件到这里",
            }
        }]
    }
}

function emptyPageData(): ComponentData {
    return {
        type: MasterPage.name,
        children: [defaultBodyData()]
    }
}
export let defaultPageDatas = {
    home(): ComponentData {
        return emptyPageData();
    },
    empty(): ComponentData {
        return emptyPageData();
    },
    member() {
        let pageData = emptyPageData();
        addComponentDataToBody(pageData, {
            type: MemberPage.name, props: { selected: true }
        });
        return pageData;
    },
    menu() {
        let pageData = emptyPageData();
        addComponentDataToFooter(pageData, {
            type: Menu.name, props: { selected: true }
        })
        return pageData;
    },
    shoppingCart() {
        let pageData = emptyPageData();
        addComponentDataToHeader(pageData, {
            type: ShoppingCartHeader.name
        })
        addComponentDataToBody(pageData, {
            type: ShoppingCart.name, props: { selected: true }
        })
        addComponentDataToFooter(pageData, {
            type: ShoppingCartFooter.name
        })

        return pageData;
    },
    categories() {
        let pageData = emptyPageData();
        addComponentDataToBody(pageData, {
            type: Categories.name,
            props: { selected: true }
        })

        return pageData;
    },
    product() {
        let pageData = emptyPageData();
        addComponentDataToBody(pageData, {
            type: Carousel.name
        });
        addComponentDataToBody(pageData, {
            type: ProductInfo.name,
            props: { selected: true }
        });
        addComponentDataToFooter(pageData, {
            type: ProductInfoFooter.name,
        });
        return pageData;
    },
    storeCoupons() {
        let pageData = emptyPageData();
        addComponentDataToBody(pageData, {
            type: StoreCoupons.name, props: { selected: true }
        });
        return pageData;
    }
}

let localService = createService(LocalService);
export let pageDatas = {
    home: async function (): Promise<PageDataRecord> {
        return getPageDataRecord("home");
    },
    member: async function (): Promise<PageDataRecord> {
        return getPageDataRecord("member");
    },
    menu: async function (): Promise<PageDataRecord> {
        return getPageDataRecord("menu");
    },
    shoppingCart: async function (): Promise<PageDataRecord> {
        return getPageDataRecord("shoppingCart");
    },
    categories: async function (): Promise<PageDataRecord> {
        return getPageDataRecord("categories")
    },
    product() {
        return getPageDataRecord("product");
    },
    storeCoupons() {
        return getPageDataRecord("storeCoupons")
    }
}

async function getPageDataRecord(name: keyof typeof defaultPageDatas): Promise<PageDataRecord> {
    let reocrd = await localService.getPageDataRecordByName(name);
    if (reocrd == null) {
        let pageData = defaultPageDatas[name]();
        return { pageData, name, type: "page" } as PageDataRecord
    }
    return reocrd;
}

function getBodyContainerId(componentData: ComponentData) {
    return getPartyContainerId(BODY_TAG, componentData);
}

function getFooterContainerId(componentData: ComponentData) {
    return getPartyContainerId(FOOTER_TAG, componentData);
}

function getHeaderContainerId(componentData: ComponentData) {
    return getPartyContainerId(HEADER_TAG, componentData);
}


export function getPartyContainerId(tagName: PagePartTag, componentData: ComponentData) {
    let stack = new Array<ComponentData>();
    stack.push(componentData);
    while (stack.length > 0) {
        let item = stack.pop();
        if (item.type == tagName) {
            let containerData = item.children.filter(o => o.type == ComponentContainer.name)[0];
            if (containerData)
                return containerData.props.id;

            return null;
        }

        if (item.children)
            stack.push(...item.children);
    }
}

export function addComponentDataToHeader(pageData: ComponentData, item: ComponentData) {
    let headerData = pageData.children.filter(o => o.type == HEADER_TAG)[0];
    if (headerData == null) {
        pageData.children.push(defaultHeaderData());
    }
    let containerId = getHeaderContainerId(pageData);
    console.assert(containerId != null);
    item.props = item.props || {};
    item.props.parentId = containerId;
    pageData.children.push(item);
}

export function addComponentDataToBody(pageData: ComponentData, item: ComponentData) {
    let containerId = getBodyContainerId(pageData);
    console.assert(containerId != null);
    item.props = item.props || {};
    item.props.parentId = containerId;
    pageData.children.push(item);
}

export function addComponentDataToFooter(pageData: ComponentData, item: ComponentData) {

    let footerData = pageData.children.filter(o => o.type == FOOTER_TAG)[0];
    if (footerData == null) {
        pageData.children.push(defaultFooterData());
    }

    let containerId = getFooterContainerId(pageData);
    console.assert(containerId != null);
    item.props = item.props || {};
    item.props.parentId = containerId;
    pageData.children.push(item);
}

export function removeChildComponentData(pageData: ComponentData, type: string) {
    pageData.children = pageData.children.filter(o => o.type != type);
    return pageData;
}

export function removeComponentDataFromFooter(pageData: ComponentData, type: string) {
    let footerData = pageData.children.filter(o => o.type == FOOTER_TAG)[0];
    if (footerData == null) {
        return;
    }

    let containerId = getFooterContainerId(pageData);
    pageData.children = pageData.children.filter(o => !(o.type == type && o.props.parentId == containerId));

    //===========================================================================================
    // 如果 footer 没有子组件，移除 footer
    let footerChildren = pageData.children.filter(o => o.props.parentId == containerId);
    if (footerChildren.length == 0) {
        pageData.children = pageData.children.filter(o => o.props.id != footerData.props.id);
    }
    //===========================================================================================
    return pageData;
}

export function findChildComponentData(componentData: ComponentData, type: string) {
    let stack = [...(componentData.children || [])];
    while (stack.length > 0) {
        let item = stack.shift();
        if (item.type == type)
            return item;

        stack.push(...item.children || []);
    }

    return null;
}

export interface FooterComponentData extends ComponentData {
    showMenu?: boolean,
    showSettlement?: boolean,
}

export function findFooterComponentData(componentData: ComponentData): FooterComponentData {
    let footerData = findChildComponentData(componentData, FOOTER_TAG);
    return footerData;
}